Skip to content

Refactor: Refactored background persistence behavior (SessionKeepAliveService), NotificationHelper, and LogManager.#609

Draft
Juan-Antonio-Doe wants to merge 24 commits into
WinNative-Emu:mainfrom
Juan-Antonio-Doe:background-persistance-fix-2
Draft

Refactor: Refactored background persistence behavior (SessionKeepAliveService), NotificationHelper, and LogManager.#609
Juan-Antonio-Doe wants to merge 24 commits into
WinNative-Emu:mainfrom
Juan-Antonio-Doe:background-persistance-fix-2

Conversation

@Juan-Antonio-Doe

Copy link
Copy Markdown
Contributor

Main user changes:

  • The persistence in the background should have been improved, including optional settings in the menu to enhance background persistence if needed, without users who don’t have this issue being affected by increased battery drain in the background.
    • Simple background persistence (just the foreground service) enabled by default in settings.
    • Option to automatically pause the session when entering the background or locking the device.
    • The wakelock option may increase battery consumption in the background compared to when the emulators previously ran without issues. This option could fix the following problems that occur when returning from the background: the container closing, loss of sound, and the game slowing down to single-digit FPS.
    • The "heartbeat" setting could further improve the persistence of the game/container while running in the background. In my tests and logs it has proven to be pretty useless, but if wakeLock does not work, this option might help. Recommended value if enabled: 120 seconds, then gradually reduce it if the problem persists.
    • Now you can choose between different process pause behaviors; previously, only the game was paused.

Main tester changes:

  • Improved LogManager with new features, some of which are:

    • A tag and text filter accessible from the app’s debug section.
    • The ability to obtain log files that include the reason why the app closed previously, or a log file focused exclusively on crashes.
    • With a specific ADB permissions, the ability to record system logs related to the OS killing background app processes.
    • Log files are now saved directly in the WN external folder configured in settings.

    Main developer changes:

  • Refactored NotificationHelper so it can be used by classes other than those related to Stores.

  • SessionKeepAliveService is now the "Master foreground service" (MFS). The stores now work with a normal service, and this is protected by MFS. (WIP - currently SteamService only).

    • This way, there is no longer a need to have a different notification for each store.
  • Configured Timber logs to work with debug apks (initialized in UnifiedActivity.kt)

    • Previously, Timber logs didn't work at all.

Fixes:

  • Fixed a silent crash in Client.java and XConnectorEpoll.java when killing processes after closing the container.
  • XServerDisplayActivity: The container/game no longer appears on top of the lock screen.
  • SteamService: Fixed a crash that could occur during game startup, causing an infinite loop on the container initialization screen.

Juan-Antonio-Doe and others added 24 commits June 27, 2026 22:58
… NotificationHelper, and LogManager.

Main changes:
- Refactored and optimized the SessionKeepAliveService class with the following changes:
  - Converted into the master class for the app’s general foreground service.
    - The foreground service starts in this class whenever there is any other class that needs to prevent the app from being killed by the OS.
       - Changed the Foreground type from SpecialUse to DataSync and commented out the wakelock code. DataSync should be sufficient.
       - SteamService calls this class when it starts its own normal service.
       - XServerDisplayActivity calls this class when it starts.
    - All foreground-related notifications are updated with the relevant messages.
       -  The game/container session now offers the option to close the container from the notification.
  - Previous code and code that proved not useful in the tests performed have been commented out. It will be removed once it’s confirmed that the current changes work and that this code is no longer required.
- Refactored the NotificationHelper class to be independent of the stores and usable more generally and broadly.
  - The class now handles, in general, based on the parameters provided:
    - Create the notification channel.
    - Create the notification with the given parameters.
    - Update the notifications.
    - Generate a specific ID for each notification based on the package name and a string defined in each class that requires a notification.
- Refactored the LogManager class:
  - Regular logs (Log.d, Log.w, Timber.d, Timber.e, etc.) can now be replaced by LogManager methods while preserving their functionality, and in addition to gaining access to them from the text files generated by the class without needing to use logcat.
  - Included a Watcher for when the container goes into pause due to backgrounding, to determine what caused the container to be closed.
    - To be more useful, it requires a special permission in the manifest that allows reading system logs. This grants access to logs such as ActivityManager logs, for example, which is responsible for killing background processes.
  - Included the ability to know why the app previously closed.
  - Included the ability to extract crash logs that recently affected the app.

Other changes:
- ProcessHelper:
  - Commented out the code that modifies each process's OOM score (need to verify its usefulness with adb)
  - Commented out the code that leaves some wine processes and others unpaused. Other forks don’t have issues with all processes paused.
  - Fixed an error with readAllBytes() from InputStream that crashes on Android versions below API 33.
- Store services:
  - In Epic and GOG, moved the variables to the top of the class for better organization.
  - SteamService migrated the foreground service to SessionKeepAliveService and replaced it with a normal service.
    - SteamLogin classes: Fixed a crash related to the migration of the foreground service.
- Configured Timber logs to work with debug apks (initialized in UnifiedActivity.kt)
- Client.java and XConnectorEpoll.java:
  - Fixed a silent crash that was thought to be responsible for the container closing. It seems not to be the case.
- AndroidManifest: Removed WakeLock permission and temporarily added READ_LOGS to obtain more details in logs related to background activity.
- XServerDisplayActivity: The line that forced the container to render on top of the lock screen has been commented out.
# Conflicts:
#	app/src/main/runtime/display/XServerDisplayActivity.java
Other changes:
- Removed unused imports.
- Replaced a `Log.w` with `Timber.w`.
This commit introduces a more robust logging and diagnostic framework.

- Automated Tag Collection: Added `gradle/collectLogTags.gradle` to scan source files for log tags and generate a `GeneratedLogTags` object at build time, ensuring the UI always has an up-to-date list of available tags.
- Enhanced LogManager:
    - Implemented granular tag filtering with support for `ALL`, `INCLUDE`, and `EXCLUDE` modes.
    - Added support for manual text filters and custom user-defined tags.
    - Expanded diagnostic logging to include dedicated files for native crashes (`crash.log`) and detailed application exit reasons (`exit_reasons.log`) using `ApplicationExitInfo`.
    - Refactored `startPauseWatch` into `startEventWatch`, providing better logcat filter specifications and label-based log files.
- UI Integration: Updated `DebugFragment` and `DebugScreen` to provide controls for the new logging features, including tag selection, filter mode toggles, and manual text filtering.
- Build System: Integrated the `collectLogTags` task into the `app` module's `preBuild` step and configured source sets to include generated code.
- Added translations for the following languages:
  - Spanish
  - German
  - French
  - Italian
- Remove redundant line in SessionKeepAliveService - onTimeout() method.

- Updated XServerDisplayActivity with the refactored new LogManager and added some more logs.
Added more logs to:
- VulkanRenderer
- XConnectorEpoll
  - Added a `reason` parameter to `killConnection` method for get a more detailed description of what is happening and why.
- XServerSurfaceView
…ugs/crashes

This update introduces a configurable background protection system designed to improve session stability when the app is in the background. It also enhances diagnostic capabilities by providing more detailed crash and exit reason reporting.

Key changes include:
- Background Protection: Added an optional heartbeat mechanism and optional CPU `WAKE_LOCK` to prevent aggressive OOM killing by the OS or avoid issues related to the phone deep sleep mode.
- Process Management: Introduced `BackgroundPauseMode` (All, Game Only, or All except Game), allowing users to customize which processes are suspended when the session is paused.
- Improved Logging: Updated `LogManager` to capture detailed `ApplicationExitInfo`, including traces for ANRs, Java crashes, and native crashes.
- Service Enhancements: Integrated a new wake lock and heartbeat logic into `SessionKeepAliveService` to ensure persistent protection during background states.
- UI Other Settings: Added auto pause, wake lock, heartbeat frequency and pause mode options so the testers can try different combinations for their devices.
- UI Strings: Added new strings for background protection settings, including heartbeat frequency and auto-pause options.

Other changes:
- Fixed a crash that could occur during game startup, causing an infinite loop on the container initialization screen.
- Improved some of the UI options by hiding locked settings that require other options to be enabled. Hidden and shown with a small animation.
- Readded wake_lock permission to the AndroidManifest.
- The current setting only enables the foreground for game sessions; the wakelock remains optional, and it is probably not necessary on Android 15 or lower.
# Conflicts:
#	app/src/main/feature/settings/debug/DebugFragment.kt
#	app/src/main/feature/settings/debug/DebugScreen.kt
#	app/src/main/feature/settings/other/OtherSettingsFragment.kt
#	app/src/main/feature/settings/other/OtherSettingsScreen.kt
#	app/src/main/feature/stores/steam/service/SteamService.kt
#	app/src/main/runtime/display/renderer/VulkanRenderer.java
#	app/src/main/runtime/system/LogManager.kt
#	app/src/main/shared/android/NotificationHelper.kt
…enus.

- Also, added a string to background toggle description/subtitle.

Note: The gamepad navigation could be broken because its implementation was made before my new UI options. A more in-depth review is required.
…navigation)

Changes:
- NotificationHelper
  - Commented out the third channel, `CHAT_BG_CHANNEL`, because it was only used to show a notification that Steam chat is still running in the background. Replaced by adding the relevant message to Winnative’s main foreground channel notification.

- SteamService
  - Commented out the code related to the previous channel, which could also cause an exception when trying to start a foreground service while the app is already in the background. In addition, the current code only needs one master foreground service, not an extra one.
  - Added some `stopComponent` lines in various parts of the code to ensure that SessionKeepAliveService stays up to date with the state of SteamService.

- DebugScreen and OtherSettingsScreen menus
  - Updated to work with the new controller navigation implementation.

- SessionKeepAliveService, build.gradle and libs.versions.toml
  - Implemented a lifecycle observer in the class to better manage the foreground, starting with the functionality of the notification to be shown and its exit button.
    - For this, build.gradle had to be modified with a new dependency, which then automatically updated libs.versions.toml as well.
  - Now the notification from the container running in the background reliably shows the Exit button.
  - If Steam chat is set to stay open when the app closes, the Exit button in the previous notification properly closes the container and keeps the app running. If it is not set that way, Exit properly closes the container and then closes the app.
  - Added a new medium-low priority message between "Download" and "Stores" in the foreground notification that will inform the user that Steam Chat is running if the app is in the background and Steam Chat is enabled.
  - Refactored some code to avoid duplicity.

- XServerDisplayActivity
  - Added a conditional to prevent Winnative from interrupting the user’s activity (appearing in the foreground while the user is doing something else) if the container has been closed from the notification (Exit) and the app is in the background.
Removed unused code.
…ame while in background.

It causes too many problems, including:
- An ANR crash if you return to the app after pressing Exit.
- The container restarts automatically when you return to the app after pressing Exit.
# Conflicts:
#	app/src/main/runtime/system/ProcessHelper.java
… Filter.

- Now system tags previously hardcoded in the recorded logs appears as custom tags in the UI, so they can be selected/unselected.
- Added a new custom tag list in LogManager for tags outside the scope of the CollectorLogTag module.
  - For example: secondary tags in classes, hardcoded tags in logs, or tags from `.c` classes.
…ice.

- Epic and GOG services are now regular services protected by the foreground service of SessionKeepAliveService.
- Updated the message for the active stores service so that it follows the specified order and correctly separates store names with commas and "and".

- Fixed a bug that caused Steam to lose foreground protection when the app was sent to the background.
- The size and processing load of crash reports has been reduced considerably.
  - Examples with ANR crashes:
    - From 280 KB to 16.5 KB.
    - From 500 KB to 22 KB.
…y disabled by the user.

This is more user-friendly for new or inexperienced users.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant